<template>
  <div class="report-designer">
    <!-- 顶部工具栏 -->
    <div class="toolbar">
      <div class="tool-group">
        <button class="tool-button" @click="saveReport">
          <i class="fas fa-save"></i>
          保存
        </button>
        <button class="tool-button" @click="previewReport">
          <i class="fas fa-eye"></i>
          预览
        </button>
        <el-dropdown @command="exportReport">
          <button class="tool-button">
            <i class="fas fa-download"></i>
            导出
          </button>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item command="pdf">PDF</el-dropdown-item>
              <el-dropdown-item command="excel">Excel</el-dropdown-item>
              <el-dropdown-item command="image">图片</el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
      </div>

      <div class="tool-group">
        <button class="tool-button" @click="addChart">
          <i class="fas fa-chart-bar"></i>
          添加图表
        </button>
        <button class="tool-button" @click="addTable">
          <i class="fas fa-table"></i>
          添加表格
        </button>
        <button class="tool-button" @click="addText">
          <i class="fas fa-font"></i>
          添加文本
        </button>
      </div>
    </div>

    <!-- 主设计区域 -->
    <div class="designer-container">
      <!-- 左侧数据源面板 -->
      <div class="datasource-panel" :class="{ 'collapsed': isLeftPanelCollapsed }">
        <div class="panel-header">
          <h3>数据源</h3>
          <div class="panel-actions">
            <button class="add-button" @click="showDataSourceDialog" v-show="!isLeftPanelCollapsed">
              <i class="fas fa-plus"></i>
            </button>
            <button class="collapse-button" @click="toggleLeftPanel">
              <i class="fas" :class="isLeftPanelCollapsed ? 'fa-chevron-right' : 'fa-chevron-left'"></i>
            </button>
          </div>
        </div>
        
        <div class="datasource-list">
          <div v-for="ds in dataSources" 
               :key="ds.id"
               class="datasource-item"
               @click="selectDataSource(ds)">
            <i class="fas fa-database"></i>
            <span class="ds-name">{{ ds.name }}</span>
            <div class="ds-actions">
              <i class="fas fa-edit" @click.stop="editDataSource(ds)"></i>
              <i class="fas fa-trash" @click.stop="deleteDataSource(ds)"></i>
            </div>
          </div>
        </div>
      </div>

      <!-- 中间设计画布 -->
      <div class="design-canvas" ref="canvas">
        <!-- 水平标尺 -->
        <div class="ruler ruler-h" ref="rulerH">
          <canvas ref="rulerHCanvas"></canvas>
          <div class="ruler-indicator-h" :style="{ left: mouseX + 'px' }"></div>
        </div>
        
        <!-- 垂直标尺 -->
        <div class="ruler ruler-v" ref="rulerV">
          <canvas ref="rulerVCanvas"></canvas>
          <div class="ruler-indicator-v" :style="{ top: mouseY + 'px' }"></div>
        </div>
        
        <!-- 标尺角落 -->
        <div class="ruler-corner"></div>
        
        <!-- 添加网格容器 -->
        <div class="grid-background"></div>
        
        <!-- 组件列表 -->
        <ResizableContainer
          v-for="component in reportComponents"
          :key="component.id"
          :component="component"
          :is-selected="selectedComponent?.id === component.id"
          @select="selectComponent(component)"
          @update="handleComponentUpdate"
          @duplicate="duplicateComponent(component)"
          @delete="deleteComponent(component)">
          
          <TextComponent
            v-if="component.type === 'text'"
            :component="component"
            @update="handleComponentUpdate" />
            
          <ChartComponent
            v-else-if="component.type === 'chart'"
            :component="component" />
            
          <TableComponent
            v-else-if="component.type === 'table'"
            :component="component" />
            
        </ResizableContainer>
      </div>

      <!-- 右侧属性面板 -->
      <div class="properties-panel" :class="{ 'collapsed': isPanelCollapsed }">
        <div class="panel-header">
          <h3>属性设置</h3>
          <button class="collapse-button" @click="togglePanel">
            <i class="fas" :class="isPanelCollapsed ? 'fa-chevron-left' : 'fa-chevron-right'"></i>
          </button>
        </div>
        
        <div v-if="selectedComponent" class="properties-content">
          <!-- 通用属性 -->
          <div class="property-group">
            <h4>基本属性</h4>
            <div class="property-item">
              <label>标题</label>
              <input v-model="selectedComponent.title" @change="handleComponentUpdate">
            </div>
            <div class="property-item">
              <label>宽度</label>
              <input type="number" v-model="selectedComponent.width" @change="handleComponentUpdate">
            </div>
            <div class="property-item">
              <label>高度</label>
              <input type="number" v-model="selectedComponent.height" @change="handleComponentUpdate">
            </div>
          </div>

          <!-- 图表特有属性 -->
          <template v-if="selectedComponent.type === 'chart'">
            <div class="property-group">
              <h4>图表设置</h4>
              <div class="property-item">
                <label>图表类型</label>
                <select v-model="selectedComponent.chartType" @change="handleComponentUpdate">
                  <option value="line">折线图</option>
                  <option value="bar">柱状图</option>
                  <option value="pie">饼图</option>
                  <option value="scatter">散点图</option>
                  <option value="area">面积图</option>
                  <option value="radar">雷达图</option>
                  <option value="gauge">仪表盘</option>
                  <option value="funnel">漏斗图</option>
                  <option value="heatmap">热力图</option>
                  <option value="tree">树图</option>
                </select>
              </div>
              
              <!-- 样式配置 -->
              <div class="property-item">
                <label>主题色</label>
                <el-color-picker v-model="selectedComponent.themeColor" @change="handleComponentUpdate" />
              </div>
              
              <div class="property-item">
                <label>是否平滑</label>
                <el-switch v-model="selectedComponent.smooth" @change="handleComponentUpdate" />
              </div>
              
              <div class="property-item">
                <label>显示数值</label>
                <el-switch v-model="selectedComponent.showLabel" @change="handleComponentUpdate" />
              </div>
            </div>

            <!-- 数据配置 -->
            <div class="property-group">
              <h4>数据设置</h4>
              <div class="property-item">
                <label>数据源</label>
                <select v-model="selectedComponent.dataSource" @change="handleComponentUpdate">
                  <option v-for="ds in dataSources" 
                          :key="ds.id" 
                          :value="ds.id">
                    {{ ds.name }}
                  </option>
                </select>
              </div>
              
              <div class="property-item">
                <label>刷新间隔(秒)</label>
                <el-input-number 
                  v-model="selectedComponent.refreshInterval" 
                  :min="0" 
                  :step="5"
                  @change="setupAutoRefresh(selectedComponent)" 
                />
              </div>
            </div>
          </template>

          <!-- 表格特有属性 -->
          <template v-if="selectedComponent.type === 'table'">
            <div class="property-group">
              <h4>表格设置</h4>
              <div class="property-item">
                <label>数据源</label>
                <select v-model="selectedComponent.dataSource" @change="handleComponentUpdate">
                  <option v-for="ds in dataSources" 
                          :key="ds.id" 
                          :value="ds.id">
                    {{ ds.name }}
                  </option>
                </select>
              </div>
              <div class="property-item">
                <label>列设置</label>
                <div class="column-list">
                  <div v-for="(col, index) in selectedComponent.columns"
                       :key="index"
                       class="column-item">
                    <input v-model="col.label" placeholder="列标题">
                    <input v-model="col.prop" placeholder="字段名">
                    <i class="fas fa-times" @click="removeColumn(index)"></i>
                  </div>
                  <button class="add-column" @click="addColumn">
                    <i class="fas fa-plus"></i> 添加列
                  </button>
                </div>
              </div>
            </div>
          </template>

          <!-- 文本特有属性 -->
          <template v-if="selectedComponent.type === 'text'">
            <div class="property-group">
              <h4>文本设置</h4>
              <div class="property-item">
                <label>内容</label>
                <textarea v-model="selectedComponent.content" 
                         @change="handleComponentUpdate"
                         rows="4">
                </textarea>
              </div>
              <div class="property-item">
                <label>字体大小</label>
                <input type="number" 
                       v-model="selectedComponent.fontSize" 
                       @change="handleComponentUpdate">
              </div>
              <div class="property-item">
                <label>对齐方式</label>
                <select v-model="selectedComponent.textAlign" @change="handleComponentUpdate">
                  <option value="left">左对齐</option>
                  <option value="center">居中</option>
                  <option value="right">右对齐</option>
                </select>
              </div>
            </div>
          </template>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, computed, nextTick, onUnmounted, watch } from 'vue'
import * as echarts from 'echarts'
import { ElMessage } from 'element-plus'
import ResizableContainer from './components/ResizableContainer.vue'
import TextComponent from './components/TextComponent.vue'
import ChartComponent from './components/ChartComponent.vue'
import TableComponent from './components/TableComponent.vue'
import { useRoute, useRouter } from 'vue-router'

const route = useRoute()
const router = useRouter()

// 数据源列表
const dataSources = ref([])
// 报表组件列表
const reportComponents = ref([])
// 当前选中的组件
const selectedComponent = ref(null)
// 画布引用
const canvas = ref(null)
// 图表实例Map
const chartInstances = new Map()

// 添加面板折叠状态
const isPanelCollapsed = ref(false)

// 添加标尺相关的响应式变量
const rulerHCanvas = ref(null)
const rulerVCanvas = ref(null)
const mouseX = ref(0)
const mouseY = ref(0)
const RULER_SIZE = 20
const RULER_SCALE = 10

// 左侧面板折叠状态
const isLeftPanelCollapsed = ref(false)

// 添加调整大小相关的状态
const isResizing = ref(false)
const resizeType = ref(null)
const resizeStartPos = ref({ x: 0, y: 0 })
const resizeStartSize = ref({ width: 0, height: 0 })
const resizeStartCoord = ref({ x: 0, y: 0 })

// 初始化数据
onMounted(() => {
  console.log('组件挂载，开始初始化')
  loadDataSources()
  initReport()
  
  // 添加键盘事件监听，用于微调选中组件位置
  document.addEventListener('keydown', handleKeyDown)
  initRulers()
  canvas.value.addEventListener('mousemove', updateRulerIndicators)
})

// 组件卸载时移除事件监听
onUnmounted(() => {
  document.removeEventListener('keydown', handleKeyDown)
  chartInstances.forEach(chart => {
    chart.dispose()
  })
  chartInstances.clear()
})

// 加载数据源列表
const loadDataSources = async () => {
  try {
    const response = await fetch('/api/datasources')
    dataSources.value = await response.json()
  } catch (error) {
    ElMessage.error('加载数据源失败')
  }
}

// 初始化报表数据
const initReport = async () => {
  try {
    const reportId = route.params.id
    console.log('当前报表ID:', reportId)

    // 模拟加载报表数据
    reportComponents.value = [
      {
        id: 1,
        type: 'text',
        content: '示例文本',
        x: 100,
        y: 100,
        width: 200,
        height: 100
      }
    ]

    // 初始化图表
    nextTick(() => {
      reportComponents.value.forEach(component => {
        if (component.type === 'chart') {
          initChart(component)
        }
      })
    })
  } catch (error) {
    console.error('初始化报表失败:', error)
    ElMessage.error('加载报表失败')
    router.push('/report/list')
  }
}

// 初始化图表
const initChart = (component) => {
  nextTick(() => {
    const chartDom = document.getElementById(`chart-${component.id}`)
    if (!chartDom) return
    
    // 如果已存在实例，先销毁
    if (chartInstances.has(component.id)) {
      chartInstances.get(component.id).dispose()
    }
    
    const chart = echarts.init(chartDom)
    chartInstances.set(component.id, chart)
    
    const option = generateChartOption(component)
    chart.setOption(option)
    
    // 监听容器大小变化
    const resizeObserver = new ResizeObserver(() => {
      chart.resize()
    })
    resizeObserver.observe(chartDom)
  })
}

// 生成图表配置
const generateChartOption = (component) => {
  const { chartType, data, title, themeColor, smooth, showLabel } = component
  
  // 基础配置
  const baseOption = {
    title: { 
      text: title,
      textStyle: {
        color: 'var(--theme-text-color, #1e293b)'
      }
    },
    tooltip: { 
      trigger: 'axis',
      backgroundColor: 'var(--theme-container-bg, #ffffff)',
      borderColor: 'var(--theme-border-color, #e2e8f0)',
      textStyle: {
        color: 'var(--theme-text-color, #1e293b)'
      }
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    legend: {
      textStyle: {
        color: 'var(--theme-text-color, #64748b)'
      }
    }
  }
  
  // 根据图表类型生成具体配置
  switch (chartType) {
    case 'line':
      return {
        ...baseOption,
        xAxis: {
          type: 'category',
          data: data.xAxis,
          axisLine: {
            lineStyle: {
              color: 'var(--theme-border-color, #e2e8f0)'
            }
          },
          axisLabel: {
            color: 'var(--theme-text-color, #64748b)'
          }
        },
        yAxis: {
          type: 'value',
          axisLine: {
            lineStyle: {
              color: 'var(--theme-border-color, #e2e8f0)'
            }
          },
          axisLabel: {
            color: 'var(--theme-text-color, #64748b)'
          }
        },
        series: data.series.map(item => ({
          name: item.name,
          type: 'line',
          data: item.data,
          smooth: smooth,
          itemStyle: {
            color: themeColor
          },
          label: {
            show: showLabel,
            position: 'top'
          }
        }))
      }
    case 'bar':
      return {
        ...baseOption,
        xAxis: {
          type: 'category',
          data: data.xAxis,
          axisLine: {
            lineStyle: {
              color: 'var(--theme-border-color, #e2e8f0)'
            }
          }
        },
        yAxis: {
          type: 'value',
          axisLine: {
            lineStyle: {
              color: 'var(--theme-border-color, #e2e8f0)'
            }
          }
        },
        series: data.series.map(item => ({
          name: item.name,
          type: 'bar',
          data: item.data,
          itemStyle: { color: themeColor },
          label: { show: showLabel, position: 'top' }
        }))
      }
    case 'pie':
      return {
        ...baseOption,
        series: [{
          type: 'pie',
          radius: '50%',
          data: data.series[0].data.map((value, index) => ({
            name: data.xAxis[index],
            value: value
          })),
          itemStyle: { color: themeColor },
          label: { show: showLabel }
        }]
      }
    case 'radar':
      return {
        ...baseOption,
        radar: {
          indicator: data.xAxis.map(name => ({ name, max: Math.max(...data.series[0].data) })),
          axisLine: { lineStyle: { color: 'var(--theme-border-color)' } }
        },
        series: [{
          type: 'radar',
          data: data.series.map(item => ({
            name: item.name,
            value: item.data,
            itemStyle: { color: themeColor }
          }))
        }]
      }
    case 'gauge':
      return {
        ...baseOption,
        series: [{
          type: 'gauge',
          data: [{ value: data.series[0].data[0], name: data.series[0].name }],
          itemStyle: { color: themeColor },
          detail: { formatter: '{value}%' }
        }]
      }
    case 'funnel':
      return {
        ...baseOption,
        series: [{
          type: 'funnel',
          data: data.xAxis.map((name, index) => ({
            name,
            value: data.series[0].data[index]
          })),
          itemStyle: { color: themeColor },
          label: { show: showLabel }
        }]
      }
    default:
      return baseOption
  }
}

// 添加图表
const addChart = () => {
  const newChart = {
    id: Date.now(),
    type: 'chart',
    chartType: 'line',
    title: '新建图表',
    x: 0,
    y: 0,
    width: 400,
    height: 300,
    data: {
      xAxis: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
      series: [{
        name: '系列1',
        data: [150, 230, 224, 218, 135, 147, 260]
      }]
    }
  }
  
  reportComponents.value.push(newChart)
  nextTick(() => {
    initChart(newChart)
    selectComponent(newChart)
  })
}

// 添加表格
const addTable = () => {
  const newTable = {
    id: Date.now(),
    type: 'table',
    title: '新表格',
    width: 500,
    height: 300,
    x: 0,
    y: 0,
    columns: [
      { prop: 'date', label: '日期' },
      { prop: 'name', label: '名称' },
      { prop: 'value', label: '数值' }
    ],
    data: [
      { date: '2024-01-15', name: '示例1', value: 100 },
      { date: '2024-01-16', name: '示例2', value: 200 }
    ]
  }
  
  reportComponents.value.push(newTable)
  selectComponent(newTable)
}

// 添加文本
const addText = () => {
  const newText = {
    id: Date.now(),
    type: 'text',
    title: '新文本',
    width: 200,
    height: 100,
    x: 0,
    y: 0,
    content: '点击编辑文本内容'
  }
  
  reportComponents.value.push(newText)
  selectComponent(newText)
}

// 选择组件
const selectComponent = (component) => {
  selectedComponent.value = component
}

// 更新组件
const handleComponentUpdate = (updatedComponent) => {
  const index = reportComponents.value.findIndex(c => c.id === updatedComponent.id)
  if (index > -1) {
    reportComponents.value[index] = { ...updatedComponent }
    
    // 如果是图表，需要更新图表
    if (updatedComponent.type === 'chart') {
      nextTick(() => {
        const chart = chartInstances.get(updatedComponent.id)
        if (chart) {
          chart.resize()
          chart.setOption(generateChartOption(updatedComponent))
        }
      })
    }
  }
}

// 复制组件
const duplicateComponent = (component) => {
  const newComponent = {
    ...component,
    id: Date.now(),
    x: component.x + 20,
    y: component.y + 20
  }
  
  reportComponents.value.push(newComponent)
  nextTick(() => {
    if (component.type === 'chart') {
      initChart(newComponent)
    }
    selectComponent(newComponent)
  })
}

// 删除组件
const deleteComponent = (component) => {
  const index = reportComponents.value.findIndex(c => c.id === component.id)
  if (index > -1) {
    if (component.type === 'chart') {
      const chart = chartInstances.get(component.id)
      if (chart) {
        chart.dispose()
        chartInstances.delete(component.id)
      }
    }
    reportComponents.value.splice(index, 1)
    if (selectedComponent.value?.id === component.id) {
      selectedComponent.value = null
    }
  }
}

// 保存报表
const saveReport = async () => {
  try {
    const reportId = route.params.id
    
    const reportData = {
      id: reportId,
      components: reportComponents.value,
      updateTime: new Date().toISOString()
    }
    
    const response = await fetch(`/api/reports/${reportId}`, {
      method: 'PUT',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(reportData)
    })
    
    const result = await response.json()
    
    if (result.success) {
      ElMessage.success('保存成功')
    } else {
      throw new Error('保存失败')
    }
  } catch (error) {
    ElMessage.error('保存失败')
  }
}

// 预览报表
const previewReport = () => {
  const previewWindow = window.open('', '_blank', 'width=1024,height=768')
  
  const previewHtml = `<!DOCTYPE html><html><head><title>报表预览</title><link href="https://cdn.jsdelivr.net/npm/element-plus/dist/index.css" rel="stylesheet"><script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"><\/script><style>body{margin:0;padding:20px;background:#f5f5f5;font-family:Arial,sans-serif}.preview-container{max-width:1200px;margin:0 auto;background:#fff;padding:20px;border-radius:8px;box-shadow:0 2px 12px rgba(0,0,0,0.1)}.component-wrapper{margin-bottom:20px;padding:16px;border:1px solid #e5e7eb;border-radius:4px}.component-title{margin:0 0 16px;font-size:16px;color:#374151}.chart-container{width:100%;height:400px}.table-container{width:100%;overflow-x:auto}.text-container{font-size:14px;line-height:1.6;color:#374151}</style></head><body><div class="preview-container">${reportComponents.value.map(component => `<div class="component-wrapper">${component.title ? `<h3 class="component-title">${component.title}</h3>` : ''}<div class="${component.type}-container" id="preview-${component.id}">${component.type === 'text' ? component.content : ''}</div></div>`).join('')}</div><script>window.onload=()=>{const components=${JSON.stringify(reportComponents.value)};components.forEach(component=>{if(component.type==='chart'){const chart=echarts.init(document.getElementById('preview-'+component.id));chart.setOption(${JSON.stringify(generateChartOption(reportComponents.value[0]))});}});};<\/script></body></html>`

  previewWindow.document.write(previewHtml)
  previewWindow.document.close()
}

// 导出报表
const exportReport = async (type) => {
  try {
    switch (type) {
      case 'pdf':
        await exportPDF()
        break
      case 'excel':
        await exportExcel()
        break
      case 'image':
        await exportImage()
        break
    }
  } catch (error) {
    ElMessage.error('导出失败')
  }
}

// 导出为PDF
const exportPDF = async () => {
  const printWindow = window.open('', '_blank')
  const printHtml = `<!DOCTYPE html><html><head><title>报表导出</title><style>@media print{body{margin:0}.preview-container{box-shadow:none}}</style></head><body>${document.querySelector('.preview-container').outerHTML}</body></html>`
  
  printWindow.document.write(printHtml)
  printWindow.document.close()
  
  await new Promise(resolve => setTimeout(resolve, 1000))
  printWindow.print()
  printWindow.close()
}

// 导出为Excel
const exportExcel = async () => {
  const data = reportComponents.value.map(component => {
    if (component.type === 'table') {
      return {
        name: component.title || '表格数据',
        data: component.data
      }
    }
    return null
  }).filter(Boolean)
  
  // 调用后端API导出Excel
  const response = await fetch('/api/report/export/excel', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
  })
  
  const blob = await response.blob()
  const url = window.URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = '报表导出.xlsx'
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  window.URL.revokeObjectURL(url)
}

// 导出为图片
const exportImage = async () => {
  const canvas = document.createElement('canvas')
  const ctx = canvas.getContext('2d')
  const container = document.querySelector('.preview-container')
  
  // 设置画布大小
  canvas.width = container.offsetWidth
  canvas.height = container.offsetHeight
  
  // 转换为图片
  const data = await html2canvas(container)
  const url = data.toDataURL('image/png')
  
  // 下载图片
  const a = document.createElement('a')
  a.href = url
  a.download = '报表导出.png'
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
}

// 计算组件样式
const getComponentStyle = computed(() => (component) => {
  return {
    width: `${component.width}px`,
    height: `${component.height}px`,
    transform: `translate(${component.x}px, ${component.y}px)`
  }
})

// 处理键盘事件
const handleKeyDown = (event) => {
  if (!selectedComponent.value) return
  
  const step = event.shiftKey ? 20 : 1
  const index = reportComponents.value.findIndex(c => c.id === selectedComponent.value.id)
  
  if (index === -1) return
  
  switch (event.key) {
    case 'ArrowLeft':
      reportComponents.value[index].x = Math.max(0, reportComponents.value[index].x - step)
      event.preventDefault()
      break
    case 'ArrowRight':
      reportComponents.value[index].x += step
      event.preventDefault()
      break
    case 'ArrowUp':
      reportComponents.value[index].y = Math.max(0, reportComponents.value[index].y - step)
      event.preventDefault()
      break
    case 'ArrowDown':
      reportComponents.value[index].y += step
      event.preventDefault()
      break
  }
}

// 更新图表
const updateChart = async (component) => {
  const chart = chartInstances.get(component.id)
  if (chart) {
    const option = generateChartOption(component)
    chart.setOption(option)
    
    // 保存到后端
    await saveReportComponent(component)
  }
}

// 更新图表数据
const updateChartData = async (component) => {
  try {
    const response = await fetch(`/api/datasource/${component.dataSource}/data`)
    const data = await response.json()
    
    component.data = data
    updateChart(component)
  } catch (error) {
    ElMessage.error('获取数据失败')
  }
}

// 设置自动刷新
const setupAutoRefresh = (component) => {
  // 清除现有定时器
  if (component.refreshTimer) {
    clearInterval(component.refreshTimer)
  }
  
  // 设置新的定时器
  if (component.refreshInterval > 0) {
    component.refreshTimer = setInterval(() => {
      updateChartData(component)
    }, component.refreshInterval * 1000)
  }
}

// 保存报表组件到后端
const saveReportComponent = async (component) => {
  try {
    await fetch(`/api/report/component/${component.id}`, {
      method: 'PUT',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(component)
    })
  } catch (error) {
    ElMessage.error('保存失败')
  }
}

// 监听组件大小变化
watch(() => reportComponents.value, (newComponents) => {
  newComponents.forEach(component => {
    if (component.type === 'chart') {
      const chart = chartInstances.get(component.id)
      if (chart) {
        nextTick(() => {
          chart.resize()
        })
      }
    }
  })
}, { deep: true })

// 切换面板展开/折叠
const togglePanel = () => {
  isPanelCollapsed.value = !isPanelCollapsed.value
}

// 切换左侧面板
const toggleLeftPanel = () => {
  isLeftPanelCollapsed.value = !isLeftPanelCollapsed.value
}

// 初始化标尺
const initRulers = () => {
  nextTick(() => {
    const hCanvas = rulerHCanvas.value
    const vCanvas = rulerVCanvas.value
    if (!hCanvas || !vCanvas || !canvas.value) return

    const hCtx = hCanvas.getContext('2d')
    const vCtx = vCanvas.getContext('2d')
    
    // 设置画布大小，考虑设备像素比
    const dpr = window.devicePixelRatio || 1
    const canvasWidth = canvas.value.clientWidth - 20 // 减去左侧标尺宽度
    const canvasHeight = canvas.value.clientHeight - 20 // 减去顶部标尺高度
    
    // 水平标尺
    hCanvas.width = canvasWidth * dpr
    hCanvas.height = 20 * dpr
    hCanvas.style.width = `${canvasWidth}px`
    hCanvas.style.height = '20px'
    hCtx.scale(dpr, dpr)
    
    // 垂直标尺
    vCanvas.width = 20 * dpr
    vCanvas.height = canvasHeight * dpr
    vCanvas.style.width = '20px'
    vCanvas.style.height = `${canvasHeight}px`
    vCtx.scale(dpr, dpr)
    
    drawRulerH(hCtx, canvasWidth)
    drawRulerV(vCtx, canvasHeight)
  })
}

// 修改水平标尺绘制函数
const drawRulerH = (ctx, width) => {
  // 清空画布
  ctx.clearRect(0, 0, width, 20)
  
  // 填充背景
  ctx.fillStyle = '#f5f5f5'
  ctx.fillRect(0, 0, width, 20)
  
  // 绘制刻度
  ctx.beginPath()
  ctx.strokeStyle = '#999'
  ctx.font = '10px Arial'
  ctx.textAlign = 'center'
  ctx.fillStyle = '#666'
  
  for (let i = 0; i < width; i += 10) {
    const x = i
    if (i % 100 === 0) {
      // 主刻度
      ctx.moveTo(x, 20)
      ctx.lineTo(x, 0)
      ctx.fillText(i.toString(), x, 15)
    } else if (i % 50 === 0) {
      // 中刻度
      ctx.moveTo(x, 20)
      ctx.lineTo(x, 5)
    } else {
      // 小刻度
      ctx.moveTo(x, 20)
      ctx.lineTo(x, 15)
    }
  }
  ctx.stroke()
}

// 修改垂直标尺绘制函数
const drawRulerV = (ctx, height) => {
  // 清空画布
  ctx.clearRect(0, 0, 20, height)
  
  // 填充背景
  ctx.fillStyle = '#f5f5f5'
  ctx.fillRect(0, 0, 20, height)
  
  // 绘制刻度
  ctx.beginPath()
  ctx.strokeStyle = '#999'
  ctx.font = '10px Arial'
  ctx.textAlign = 'right'
  ctx.fillStyle = '#666'
  
  for (let i = 0; i < height; i += 10) {
    const y = i
    if (i % 100 === 0) {
      // 主刻度
      ctx.moveTo(20, y)
      ctx.lineTo(0, y)
      ctx.save()
      ctx.translate(15, y + 4)
      ctx.rotate(-Math.PI / 2)
      ctx.fillText(i.toString(), 0, 0)
      ctx.restore()
    } else if (i % 50 === 0) {
      // 中刻度
      ctx.moveTo(20, y)
      ctx.lineTo(5, y)
    } else {
      // 小刻度
      ctx.moveTo(20, y)
      ctx.lineTo(15, y)
    }
  }
  ctx.stroke()
}

// 修改更新标尺指示器函数
const updateRulerIndicators = (event) => {
  if (!canvas.value) return
  
  const rect = canvas.value.getBoundingClientRect()
  const scrollLeft = canvas.value.scrollLeft
  const scrollTop = canvas.value.scrollTop
  
  mouseX.value = event.clientX - rect.left + scrollLeft
  mouseY.value = event.clientY - rect.top + scrollTop
}

// 添加窗口大小变化监听
onMounted(() => {
  window.addEventListener('resize', initRulers)
})

onUnmounted(() => {
  window.removeEventListener('resize', initRulers)
})

// 开始调整大小
const startResize = (event, component, type) => {
  event.preventDefault()
  isResizing.value = true
  resizeType.value = type
  resizeStartPos.value = {
    x: event.clientX,
    y: event.clientY
  }
  resizeStartSize.value = {
    width: component.width,
    height: component.height
  }
  resizeStartCoord.value = {
    x: component.x,
    y: component.y
  }
  
  document.addEventListener('mousemove', handleResize)
  document.addEventListener('mouseup', stopResize)
  
  // 选中当前组件
  selectComponent(component)
}

// 处理调整大小
const handleResize = (event) => {
  if (!isResizing.value || !selectedComponent.value) return
  
  const dx = Math.round((event.clientX - resizeStartPos.value.x) / 20) * 20
  const dy = Math.round((event.clientY - resizeStartPos.value.y) / 20) * 20
  
  const minWidth = 100
  const minHeight = 100
  
  const index = reportComponents.value.findIndex(c => c.id === selectedComponent.value.id)
  if (index === -1) return
  
  const newSize = { ...resizeStartSize.value }
  const newCoord = { ...resizeStartCoord.value }
  
  switch (resizeType.value) {
    case 'top-left':
      newSize.width = Math.max(minWidth, resizeStartSize.value.width - dx)
      newSize.height = Math.max(minHeight, resizeStartSize.value.height - dy)
      newCoord.x = resizeStartCoord.value.x + (resizeStartSize.value.width - newSize.width)
      newCoord.y = resizeStartCoord.value.y + (resizeStartSize.value.height - newSize.height)
      break
    case 'top':
      newSize.height = Math.max(minHeight, resizeStartSize.value.height - dy)
      newCoord.y = resizeStartCoord.value.y + (resizeStartSize.value.height - newSize.height)
      break
    case 'top-right':
      newSize.width = Math.max(minWidth, resizeStartSize.value.width + dx)
      newSize.height = Math.max(minHeight, resizeStartSize.value.height - dy)
      newCoord.y = resizeStartCoord.value.y + (resizeStartSize.value.height - newSize.height)
      break
    case 'right':
      newSize.width = Math.max(minWidth, resizeStartSize.value.width + dx)
      break
    case 'bottom-right':
      newSize.width = Math.max(minWidth, resizeStartSize.value.width + dx)
      newSize.height = Math.max(minHeight, resizeStartSize.value.height + dy)
      break
    case 'bottom':
      newSize.height = Math.max(minHeight, resizeStartSize.value.height + dy)
      break
    case 'bottom-left':
      newSize.width = Math.max(minWidth, resizeStartSize.value.width - dx)
      newSize.height = Math.max(minHeight, resizeStartSize.value.height + dy)
      newCoord.x = resizeStartCoord.value.x + (resizeStartSize.value.width - newSize.width)
      break
    case 'left':
      newSize.width = Math.max(minWidth, resizeStartSize.value.width - dx)
      newCoord.x = resizeStartCoord.value.x + (resizeStartSize.value.width - newSize.width)
      break
  }
  
  // 更新组件大小和位置
  reportComponents.value[index] = {
    ...reportComponents.value[index],
    width: newSize.width,
    height: newSize.height,
    x: newCoord.x,
    y: newCoord.y
  }
  
  // 如果是图表，需要重新调整大小
  if (reportComponents.value[index].type === 'chart') {
    nextTick(() => {
      const chart = chartInstances.get(reportComponents.value[index].id)
      if (chart) {
        chart.resize()
      }
    })
  }
}

// 停止调整大小
const stopResize = () => {
  isResizing.value = false
  resizeType.value = null
  
  document.removeEventListener('mousemove', handleResize)
  document.removeEventListener('mouseup', stopResize)
}
</script>

<style scoped>
.report-designer {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background-color: var(--theme-bg, #f8fafc);
}

.toolbar {
  display: flex;
  gap: 16px;
  padding: 8px 16px;
  background-color: var(--theme-container-bg, #ffffff);
  border-bottom: 1px solid var(--theme-border-color, #e2e8f0);
}

.tool-group {
  display: flex;
  gap: 8px;
}

.tool-button {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: 1px solid var(--theme-border-color, #e2e8f0);
  border-radius: 4px;
  background-color: var(--theme-container-bg, #ffffff);
  color: var(--theme-text-color, #64748b);
  cursor: pointer;
  transition: all 0.2s;
}

.tool-button:hover {
  background-color: var(--theme-hover-bg, #f1f5f9);
  color: var(--theme-primary-color, #3b82f6);
}

.designer-container {
  flex: 1;
  display: flex;
  overflow: hidden;
}

.datasource-panel,
.properties-panel {
  width: 280px;
  background-color: var(--theme-container-bg, #ffffff);
  border-right: 1px solid var(--theme-border-color, #e2e8f0);
  display: flex;
  flex-direction: column;
}

.panel-header {
  padding: 12px 16px;
  border-bottom: 1px solid var(--theme-border-color, #e2e8f0);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.panel-header h3 {
  margin: 0;
  font-size: 16px;
  color: var(--theme-text-color, #1e293b);
}

.design-canvas {
  position: relative;
  flex: 1;
  overflow: auto;
  padding: 20px 20px 20px 20px;  /* 先重置内边距 */
  background-color: #fff;  /* 设置为白色背景 */
}

.report-component {
  position: absolute;
  cursor: move;
  user-select: none;
  transition: transform 0.1s ease;
  background-color: var(--theme-container-bg, #ffffff);
  border: 1px solid var(--theme-border-color, #e2e8f0);
  border-radius: 4px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.report-component.selected {
  z-index: 100;
  border-color: var(--theme-primary-color, #3b82f6);
  box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
}

.component-actions {
  position: absolute;
  top: -30px;
  right: 0;
  display: flex;
  gap: 8px;
  padding: 4px;
  background-color: var(--theme-container-bg, #ffffff);
  border: 1px solid var(--theme-border-color, #e2e8f0);
  border-radius: 4px;
}

.component-actions i {
  padding: 4px;
  cursor: pointer;
  color: var(--theme-text-color, #64748b);
}

.component-actions i:hover {
  color: var(--theme-primary-color, #3b82f6);
}

/* 添加网格背景样式 */
.grid-background {
  position: absolute;
  inset: 0;
  background-size: 20px 20px;
  background-image: 
    linear-gradient(to right, var(--theme-border-color, rgba(226, 232, 240, 0.3)) 1px, transparent 1px),
    linear-gradient(to bottom, var(--theme-border-color, rgba(226, 232, 240, 0.3)) 1px, transparent 1px);
  pointer-events: none;
}

/* 添加组件调整手柄样式 */
.component-actions .handle {
  cursor: move;
}

/* 添加图表容器样式 */
.chart-container {
  width: 100%;
  height: 100%;
  padding: 12px;
  background-color: var(--theme-container-bg);
}

.chart {
  width: 100%;
  height: 100%;
  transition: all 0.3s ease;
}

/* 添加面板折叠样式 */
.properties-panel {
  transition: width 0.3s ease;
  overflow: hidden;
}

.properties-panel.collapsed {
  width: 40px;
}

.collapse-button {
  padding: 4px 8px;
  background: none;
  border: none;
  color: var(--theme-text-color);
  cursor: pointer;
  transition: all 0.2s;
}

.collapse-button:hover {
  color: var(--theme-primary-color);
}

.properties-panel.collapsed .panel-content,
.properties-panel.collapsed .panel-header h3 {
  display: none;
}

/* 暗色主题 */
@media (prefers-color-scheme: dark) {
  .report-designer {
    background-color: var(--theme-bg, #0f172a);
  }

  .toolbar,
  .datasource-panel,
  .properties-panel,
  .report-component {
    background-color: var(--theme-container-bg, #1e293b);
    border-color: var(--theme-border-color, #334155);
  }

  .tool-button {
    background-color: var(--theme-secondary-bg, #334155);
    border-color: var(--theme-border-color, #475569);
    color: var(--theme-text-color, #e2e8f0);
  }

  .tool-button:hover {
    background-color: var(--theme-hover-bg, #475569);
  }

  .panel-header {
    border-color: var(--theme-border-color, #334155);
  }

  .panel-header h3 {
    color: var(--theme-text-color, #e2e8f0);
  }

  .grid-background {
    background-image: 
      linear-gradient(to right, var(--theme-border-color, rgba(51, 65, 85, 0.3)) 1px, transparent 1px),
      linear-gradient(to bottom, var(--theme-border-color, rgba(51, 65, 85, 0.3)) 1px, transparent 1px);
  }

  .collapse-button {
    color: var(--theme-text-color, #e2e8f0);
  }

  .collapse-button:hover {
    color: var(--theme-primary-color, #3b82f6);
  }
}

.property-group {
  padding: 16px;
  border-bottom: 1px solid var(--theme-border-color, #e2e8f0);
}

.property-item {
  margin-bottom: 12px;
}

.property-item label {
  display: block;
  margin-bottom: 4px;
  color: var(--theme-text-color, #64748b);
  font-size: 12px;
}

.property-item select,
.property-item input {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid var(--theme-border-color, #e2e8f0);
  border-radius: 4px;
  background-color: var(--theme-bg, #ffffff);
  color: var(--theme-text-color, #1e293b);
}

.property-item .el-color-picker {
  width: 100%;
}

/* 添加标尺样式 */
.ruler {
  position: absolute;
  background-color: #f5f5f5;
  z-index: 10;
}

.ruler-h {
  top: 0;
  left: 20px;  /* 使用具体像素值 */
  right: 0;
  height: 20px;  /* 使用具体像素值 */
  border-bottom: 1px solid #e0e0e0;
}

.ruler-v {
  top: 20px;  /* 使用具体像素值 */
  left: 0;
  bottom: 0;
  width: 20px;  /* 使用具体像素值 */
  border-right: 1px solid #e0e0e0;
}

.ruler-corner {
  position: absolute;
  top: 0;
  left: 0;
  width: 20px;  /* 使用具体像素值 */
  height: 20px;  /* 使用具体像素值 */
  background-color: #f5f5f5;
  border-right: 1px solid #e0e0e0;
  border-bottom: 1px solid #e0e0e0;
  z-index: 11;
}

.ruler-indicator-h,
.ruler-indicator-v {
  position: absolute;
  background-color: #1890ff;
  pointer-events: none;
}

.ruler-indicator-h {
  top: 0;
  width: 1px;
  height: 20px;  /* 使用具体像素值 */
}

.ruler-indicator-v {
  left: 0;
  width: 20px;  /* 使用具体像素值 */
  height: 1px;
}

/* 修改左侧面板折叠样式 */
.datasource-panel {
  transition: width 0.3s ease;
  overflow: hidden;
}

.datasource-panel.collapsed {
  width: 40px;
}

.datasource-panel.collapsed .datasource-list,
.datasource-panel.collapsed .panel-header h3,
.datasource-panel.collapsed .add-button {
  display: none;
}

.panel-actions {
  display: flex;
  gap: 8px;
}

/* 调整设计画布边距，为标尺留出空间 */
.design-canvas {
  padding: RULER_SIZE 20px 20px RULER_SIZE;
}

/* 暗色主题适配 */
@media (prefers-color-scheme: dark) {
  .ruler,
  .ruler-corner {
    background-color: var(--theme-container-bg, #1e293b);
    border-color: var(--theme-border-color, #334155);
  }
}

/* 添加调整手柄样式 */
.resize-handles {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.resize-handle {
  position: absolute;
  width: 8px;
  height: 8px;
  background-color: #fff;
  border: 1px solid var(--theme-primary-color, #3b82f6);
  pointer-events: all;
}

.resize-handle.top-left {
  top: -4px;
  left: -4px;
  cursor: nw-resize;
}

.resize-handle.top {
  top: -4px;
  left: 50%;
  transform: translateX(-50%);
  cursor: n-resize;
}

.resize-handle.top-right {
  top: -4px;
  right: -4px;
  cursor: ne-resize;
}

.resize-handle.right {
  top: 50%;
  right: -4px;
  transform: translateY(-50%);
  cursor: e-resize;
}

.resize-handle.bottom-right {
  bottom: -4px;
  right: -4px;
  cursor: se-resize;
}

.resize-handle.bottom {
  bottom: -4px;
  left: 50%;
  transform: translateX(-50%);
  cursor: s-resize;
}

.resize-handle.bottom-left {
  bottom: -4px;
  left: -4px;
  cursor: sw-resize;
}

.resize-handle.left {
  top: 50%;
  left: -4px;
  transform: translateY(-50%);
  cursor: w-resize;
}

/* 暗色主题适配 */
@media (prefers-color-scheme: dark) {
  .resize-handle {
    background-color: #1e293b;
  }
}
</style>
